# encoding=utf-8
import os
import tokens
import syntaxs

environments = {}
macros = {}

def eval_with_file(file):
    _tokens = tokens.read_tokens_from_file('src\\' + file + '.me')
    _syntaxs = syntaxs.read_syntaxs_from_tokens(_tokens, 'src\\' + file + '.me')

    eval_with_syntaxs(_syntaxs)

# 惰性替换机制
def eval_with_normal(name, params, file):
    global environments
    if file != '':
        if not environments.has_key(name):
            print("undefined variable:" + name)
            exit()
        syntax = environments[name]
        sname = ''
        sparam = []
        for cont in syntax['content']:
            if cont['type'] == 1:
                wstr = cont['cont']
                for i in range(0, len(syntax['params'])):
                    if i < len(params):
                        wstr = wstr.replace(syntax['params'][i], params[i])
                file_object = open('dst\\' + file, 'a')
                file_object.write(wstr)
                file_object.close()
            elif cont['type'] == 2:
                if cont['cont']['name'] != '':
                    if cont['cont']['name'] == 'For':
                        if len(cont['cont']['params']) >= 2 and macros.has_key(cont['cont']['params'][1]):
                            mparams = []
                            mparams.append(cont['cont']['params'][0])
                            for mp in macros[cont['cont']['params'][1]]:
                                mparams.append(mp)
                            eval_with_for(mparams, file)
                        else:
                            eval_with_for(cont['cont']['params'], file)
                        #eval_with_for(cont['cont']['params'], file)
                    else:
                        if len(cont['cont']['params']) >= 1 and macros.has_key(cont['cont']['params'][0]):
                            eval_with_normal(cont['cont']['name'], macros[cont['cont']['name']], file)
                        else:
                            eval_with_normal(cont['cont']['name'], cont['cont']['params'], file)
                        #eval_with_normal(cont['cont']['name'], cont['cont']['params'], file)
        

def eval_with_for(params, file):
    global environments
    plen = len(params)
    if plen == 0:
        #raise SyntaxError('for params not enough')
        return
    eplen = len(environments[params[0]]['params'])
    for i in range(0, int((plen - 1) / eplen)):
        nparams = []
        for j in range(0, eplen):
            if 1 + i * eplen + j < plen:
                nparams.append(params[1 + i * eplen + j])
        eval_with_normal(params[0], nparams, file)


def eval_with_syntaxs(syntaxs):
    global environments
    global macros
    for syntax in syntaxs:
        if syntax['syn_type'] == 1:    # 定义
            if syntax['name'] != '':
                # print syntax['name']
                environments[syntax['name']] = syntax
        elif syntax['syn_type'] == 2:    # 替换
            if syntax['name'] == 'Import':
                if len(syntax['params']) > 0:
                    eval_with_file(syntax['params'][0])
                else:
                    print('import file not found:' + 'src\\' + syntax['params'][0] + '.me')
                    exit()
            elif syntax['name'] == 'For':
                if len(syntax['params']) >= 2 and macros.has_key(syntax['params'][1]):
                    mparams = []
                    mparams.append(syntax['params'][0])
                    for mp in macros[syntax['name']]:
                        mparams.append(mp)
                    eval_with_for(mparams, syntax['file'])
                else:
                    eval_with_for(syntax['params'], syntax['file'])
            elif syntax['name'] != '':
                if len(syntax['params']) >= 1 and macros.has_key(syntax['params'][0]):
                    eval_with_normal(syntax['name'], macros[syntax['name']], syntax['file'])
                else:
                    eval_with_normal(syntax['name'], syntax['params'], syntax['file'])
            else:
                pass
                #raise SyntaxError('command is null')
        elif syntax['syn_type'] == 3:      # 定义宏
            cmd = ''
            for content in syntax['content']:
                cmd += content['cont']
            #out = os.popen(cmd)
            fp = os.popen(cmd, 'r')
            out = fp.read()
            mparams = []
            for o in out.split():
                mparams.append(o)
            macros[syntax['name']] = mparams

